/*
 * =====================================================================================
 *
 *       Filename:  gradOrient.cpp
 *
 *    Description:  Returns histogram of gradient orientation of binary image
 *
 *        Version:  1.0
 *        Created:  23/07/12 14:59:45
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Moos Hueting (mh), mooshueting@gmail.com
 *   Organization:  
 *
 * =====================================================================================
 */
#include <cv.h>
#include <highgui.h>
#include <iostream>
#include <vector>
#include <math.h>

#define N_BINS 8

using namespace std;
using namespace cv;

float gradOrientation(Mat src, char arg) {
    Mat grad_x, grad_y;

    // compute x and y gradients of image
    Sobel(src, grad_x, CV_16S, 1, 0);
    Sobel(src, grad_y, CV_16S, 0, 1);

    Size s = grad_x.size();

    vector<int> ori;

    // iterate over pixels of gradient, compute gradient direction using both x and y gradient
    for (int i=0; i < s.height; i++) {
        for (int j = 0; j < s.width; j++) {
            if (grad_x.at<signed short>(i, j) != 0 || grad_y.at<signed short>(i, j) != 0) {
                // compute direction, add pi to make all values positive
                // divide by 2*pi to get values between 0 and 1
                float direction = (atan2(grad_y.at<signed short>(i, j), grad_x.at<signed short>(i, j)) + M_PI) / (2*M_PI);
                // divide over N_BINS
                direction *= N_BINS - 1;

                direction = ceil(direction - 0.5); // round to nearest integer

                ori.push_back((int)direction);
            }
        }
    }

    float res = 0;

    for (unsigned int i = 0; i < ori.size(); i++) {
        if (ori.at(i) == arg)
            res += 1;
    }

    return (float)res / ori.size();

}
